#include <stdio.h>     // 为printf
#include <type_traits> // 为std::integral_constant

// 比较早的用法
template <typename Type>
struct GetLeftSize
{
    enum
    {
        value = 1
    };
};
// c++11推荐用法
template <typename Type>
struct Example
{
    static constexpr int value = 1; // C++11推荐用法
};
//
/*
 using value_type = T;          // 值的类型
   using type = integral_constant; // 类型本身
   constexpr operator value_type() const noexcept { return value; }  // 转换操作符
   constexpr value_type operator()() const noexcept { return value; } // 函数调用操作符
*/
template <typename Type>
struct GetLeftSize2 : std::integral_constant<int, 1>
{
};

// 在main函数前添加测试类
class A
{
};
class B : public A
{
};
class C
{
};

int main()
{
    printf("\n=== Testing enum style ===\n");
    printf("GetLeftSize<int>::value = %d\n", GetLeftSize<int>::value);

    printf("\n=== Testing static constexpr style ===\n");
    printf("Example<int>::value = %d\n", Example<int>::value);

    printf("\n=== Testing integral_constant inheritance style ===\n");
    printf("GetLeftSize2<int>::value = %d\n", GetLeftSize2<int>::value);

    printf("\n=== Testing compile-time assertions ===\n");
    static_assert(GetLeftSize<int>::value == 1, "GetLeftSize value should be 1");
    static_assert(Example<int>::value == 1, "Example value should be 1");
    static_assert(GetLeftSize2<int>::value == 1, "GetLeftSize2 value should be 1");
    printf("All static assertions passed!\n");

    printf("\n=== Testing integral_constant features ===\n");
    using MyType = GetLeftSize2<int>;

    // 1. 使用 value_type
    MyType::value_type val1 = MyType::value;
    printf("value_type val1 = %d\n", val1);

    // 2. 使用类型转换操作符
    int val2 = MyType(); // 隐式转换为int
    printf("implicit conversion val2 = %d\n", val2);

    // 3. 使用函数调用操作符
    MyType instance;
    int val3 = instance(); // 调用 operator()
    printf("function call val3 = %d\n", val3);

    // 4. 使用 type
    MyType::type another_instance;
    printf("type member val4 = %d\n", another_instance());

    printf("\n=== Testing true_type and false_type ===\n");
    std::true_type t;
    std::false_type f;

    printf("true_type value: %d\n", t());
    printf("false_type value: %d\n", f());

    bool b1 = t;
    bool b2 = f;
    printf("true_type converts to: %d\n", b1);
    printf("false_type converts to: %d\n", b2);

    static_assert(std::true_type::value == true, "true_type must be true");
    static_assert(std::false_type::value == false, "false_type must be false");
    printf("All true_type/false_type assertions passed!\n");

    printf("\n=== Testing is_integral ===\n");
    // 测试整数类型
    printf("is_integral<int>: %d\n", std::is_integral<int>::value);
    printf("is_integral<bool>: %d\n", std::is_integral<bool>::value);
    printf("is_integral<char>: %d\n", std::is_integral<char>::value);

    // 测试非整数类型
    printf("is_integral<float>: %d\n", std::is_integral<float>::value);
    printf("is_integral<double>: %d\n", std::is_integral<double>::value);
    printf("is_integral<int*>: %d\n", std::is_integral<int *>::value);

    // 编译期断言
    static_assert(std::is_integral<int>::value, "int should be integral");
    static_assert(std::is_integral<bool>::value, "bool should be integral");
    static_assert(!std::is_integral<float>::value, "float should not be integral");
    printf("All is_integral assertions passed!\n");

    // C++17 的简化语法（如果你的编译器支持）
    // printf("is_integral_v<int>: %d\n", std::is_integral_v<int>);

    printf("\n=== Testing is_same ===\n");
    // 基本类型比较
    printf("is_same<int, int>: %d\n", std::is_same<int, int>::value);
    printf("is_same<int, unsigned int>: %d\n", std::is_same<int, unsigned int>::value);
    printf("is_same<int, signed int>: %d\n", std::is_same<int, signed int>::value);

    // const/volatile 修饰符测试
    printf("is_same<int, const int>: %d\n", std::is_same<int, const int>::value);
    printf("is_same<int, volatile int>: %d\n", std::is_same<int, volatile int>::value);

    // 指针和引用测试
    printf("is_same<int, int*>: %d\n", std::is_same<int, int *>::value);
    printf("is_same<int, int&>: %d\n", std::is_same<int, int &>::value);

    // 编译期断言
    static_assert(std::is_same<int, signed int>::value, "int and signed int should be same");
    static_assert(!std::is_same<int, unsigned int>::value, "int and unsigned int should not be same");
    printf("All is_same assertions passed!\n");

    // C++17 风格（如果编译器支持）
    // printf("is_same_v<int, int>: %d\n", std::is_same_v<int, int>);

    printf("\n=== Testing is_base_of ===\n");
    // 基础继承测试
    printf("is_base_of<A, B>: %d\n", std::is_base_of<A, B>::value); // true  (A是B的基类)
    printf("is_base_of<B, A>: %d\n", std::is_base_of<B, A>::value); // false (B不是A的基类)
    printf("is_base_of<C, B>: %d\n", std::is_base_of<C, B>::value); // false (C与B无关)

    // 自反性测试（类是它自己的基类）
    printf("is_base_of<A, A>: %d\n", std::is_base_of<A, A>::value); // true

    // 使用虚继承测试
    class D : virtual public A
    {
    };
    printf("is_base_of<A, D>: %d\n", std::is_base_of<A, D>::value); // true

    // 编译期断言
    static_assert(std::is_base_of<A, B>::value, "A should be base of B");
    static_assert(!std::is_base_of<B, A>::value, "B should not be base of A");
    static_assert(!std::is_base_of<C, B>::value, "C should not be base of B");
    printf("All is_base_of assertions passed!\n");

    // C++17 风格（如果编译器支持）
    // printf("is_base_of_v<A, B>: %d\n", std::is_base_of_v<A, B>);

    printf("\n=== Testing is_convertible ===\n");
    // 指针转换测试
    printf("is_convertible<B*, A*>: %d\n", std::is_convertible<B *, A *>::value); // true  (派生类指针可转换为基类指针)
    printf("is_convertible<A*, B*>: %d\n", std::is_convertible<A *, B *>::value); // false (基类指针不能转换为派生类指针)
    printf("is_convertible<C*, A*>: %d\n", std::is_convertible<C *, A *>::value); // false (无关类不能转换)

    // 引用转换测试
    printf("is_convertible<B&, A&>: %d\n", std::is_convertible<B &, A &>::value); // true
    printf("is_convertible<A&, B&>: %d\n", std::is_convertible<A &, B &>::value); // false

    // 基本类型转换测试
    printf("is_convertible<int, double>: %d\n", std::is_convertible<int, double>::value); // true
    printf("is_convertible<float, int>: %d\n", std::is_convertible<float, int>::value);   // true
    printf("is_convertible<void, int>: %d\n", std::is_convertible<void, int>::value);     // false

    // 编译期断言
    static_assert(std::is_convertible<B *, A *>::value, "B* should be convertible to A*");
    static_assert(!std::is_convertible<A *, B *>::value, "A* should not be convertible to B*");
    static_assert(std::is_convertible<int, double>::value, "int should be convertible to double");
    printf("All is_convertible assertions passed!\n");

    // C++17 风格（如果编译器支持）
    // printf("is_convertible_v<B*, A*>: %d\n", std::is_convertible_v<B*, A*>);

    return 0;
}